/**
 * Created by Jacky.Gao on 2017-01-26.
 */
import * as utils from "../Utils.js";
import { afterRenderer } from "./CellRenderer.js";
import buildMenuConfigure from "./ContextMenu.js";
import Handsontable from "handsontable";
import $ from "jquery";
import { Message } from "element-ui";
import slashTool from "../../tools/slashTool.js";

export default class ReportTable {
  constructor (container, designer) {
    this.designer = designer;
    this.container = container;
    this.cellsMap = new Map();
    this.hot = new Handsontable(container, {
      licenseKey: "non-commercial-and-evaluation",
      colWidths: 100,
      width: "100%",
      height: 720,
      rowHeights: 23,
      startCols: 1,
      startRows: 1,
      fillHandle: {
        autoInsertRow: false
      },
      colHeaders: true,
      rowHeaders: true,
      autoColumnSize: false,
      autoRowSize: false,
      manualColumnResize: true,
      manualRowResize: true,
      maxColsNumber: 700,
      outsideClickDeselects: false,
      selectionMode: "multiple",
      externalRowCalculator: true
      // afterGetRowHeader: function (row, TH) {
      //   if (row === 0) {
      //     TH.innerHTML = `<div style="line-height:5px;transform:scale(0.5);">11</div>`;
      //   }
      // },
      // modifyRowHeight: function (height, row) {
      //   if (row === 0) {
      //     height;
      //   }
      // }
    });
    this.buildMenu();
    this.hot.addHook("afterRenderer", afterRenderer);
    this.hot.addHook("afterRowResize", (newSize, currentRow, isDoubleClick) => {
      const { context, rowIndex, colIndex } = this.designer;
      const cellDef = context.getCell(rowIndex, colIndex);
      // 刷新斜线表头
      if (cellDef && cellDef.value.type === "slash") {
        slashTool.buildSlashes(context, rowIndex, colIndex);
      }

      let rowHeights = this.hot.getSettings().rowHeights;
      let oldRowHeights = rowHeights.concat([]);
      const newRowHeights = rowHeights.concat([]);
      newRowHeights.splice(currentRow, 1, newSize);
      this.hot.updateSettings({
        rowHeights: newRowHeights,
        manualRowResize: newRowHeights
      });
      utils.undoManager.add({
        redo: () => {
          rowHeights = this.hot.getSettings().rowHeights;
          oldRowHeights = rowHeights.concat([]);
          newRowHeights.splice(currentRow, 1, newSize);
          this.hot.updateSettings({
            rowHeights: newRowHeights,
            manualRowResize: newRowHeights
          });
          this.hot.context;
        },
        undo: function () {
          this.hot.updateSettings({
            rowHeights: oldRowHeights,
            manualRowResize: oldRowHeights
          });
          this.hot.context.isModify = true;
        }
      });
      this.hot.context.isModify = true;
    });
    this.hot.addHook("afterColumnResize", (newSize, currentColumn, isDoubleClick) => {
      const { context, rowIndex, colIndex } = this.designer;
      const cellDef = context.getCell(rowIndex, colIndex);
      // 刷新斜线表头
      if (cellDef && cellDef.value.type === "slash") {
        slashTool.buildSlashes(context, rowIndex, colIndex);
      }

      let colWidths = this.hot.getSettings().colWidths;
      let newColWidths = colWidths.concat([]);
      let oldColWidths = colWidths.concat([]);
      newColWidths.splice(currentColumn, 1, newSize);
      this.hot.updateSettings({
        colWidths: newColWidths,
        manualColumnResize: newColWidths
      });
      utils.undoManager.add({
        redo: () => {
          colWidths = this.hot.getSettings().colWidths;
          newColWidths = colWidths.concat([]);
          oldColWidths = colWidths.concat([]);
          newColWidths.splice(currentColumn, 1, newSize);
          this.hot.updateSettings({
            colWidths: newColWidths,
            manualColumnResize: newColWidths
          });
          this.hot.context.isModify = true;
        },
        undo: function () {
          this.hot.updateSettings({
            colWidths: oldColWidths,
            manualColumnResize: oldColWidths
          });
          this.hot.context.isModify = true;
        }
      });
      this.hot.context.isModify = true;
    });
  }

  loadFile (file, callback) {
    const url = "/designer/loadReport";
    const data = {
      file
    };
    this.designer.ajax(url, data, res => {
      this.designer.vue.common.loaded(true);
      if (res.code !== 200) {
        Message.error("加载报表文件失败，" + res.msg);
        return;
      } else {
        Message.success("加载成功");
      }
      this.reportDef = res.data;
      this.buildReportData(this.reportDef);
      if (callback) {
        callback.call(this, this.reportDef);
      }
      this.hot.render();
      if (this.reportDef.paper.bgImage) {
        $(".ht_master").css("background", `url(${this.reportDef.paper.bgImage}) 50px 26px no-repeat`);
      } else {
        $(".ht_master").css("background", "transparent");
      }
    });
  }

  buildReportData (data) {
    this.cellsMap.clear();
    const rows = data.rows;
    const rowHeights = [];
    for (const row of rows) {
      const height = row.height;
      rowHeights.push(utils.pointToPixel(height));
    }
    const columns = data.columns;
    const colWidths = [];
    for (const col of columns) {
      const width = col.width;
      colWidths.push(utils.pointToPixel(width));
    }
    const cellsMap = data.cellsMap;
    const dataArray = [];
    const mergeCells = [];
    for (const row of rows) {
      const rowData = [];
      for (const col of columns) {
        const key = row.rowNumber + "," + col.columnNumber;
        const cell = cellsMap[key];
        if (cell) {
          this.cellsMap.set(key, cell);
          rowData.push(cell.value.value || "");
          let rowspan = cell.rowSpan;
          let colspan = cell.colSpan;
          if (rowspan > 0 || colspan > 0) {
            if (rowspan === 0) rowspan = 1;
            if (colspan === 0) colspan = 1;
            mergeCells.push({
              rowspan,
              colspan,
              row: row.rowNumber - 1,
              col: col.columnNumber - 1
            });
          }
        } else {
          rowData.push("");
        }
      }
      dataArray.push(rowData);
    }
    this.hot.loadData(dataArray);
    this.hot.updateSettings({
      colWidths,
      manualColumnResize: colWidths,
      rowHeights,
      manualRowResize: rowHeights,
      mergeCells,
      readOnly: true
    });
  }

  buildMenu () {
    this.hot.updateSettings({
      contextMenu: buildMenuConfigure()
    });
  }

  bindSelectionEvent (callback) {
    Handsontable.hooks.add(
      "afterSelectionEnd",
      function (rowIndex, colIndex, row2Index, col2Index) {
        callback.call(this, rowIndex, colIndex, row2Index, col2Index);
      },
      this.hot
    );
  }
}
